package com.cskaoyan.wordmemorize.aop_whh;

import com.cskaoyan.wordmemorize.aop_whh.annotation.OperateLog;
import com.cskaoyan.wordmemorize.auth.StpKit;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.dao.entity.OperateLogDO;
import com.cskaoyan.wordmemorize.dao.mapper.OperateLogMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
@Aspect
public class LogAspect {

    @Autowired
    OperateLogMapper operateLogMapper;

    @Autowired
    ObjectMapper objectMapper;

    @Pointcut("@annotation(com.cskaoyan.wordmemorize.aop_whh.annotation.OperateLog)")
    public void logPointcut() {

    }


    @Around("logPointcut()")
    public Object keepLog(ProceedingJoinPoint joinPoint) throws JsonProcessingException {
        //得到用户id，但是没有登录，还不能获取
        Long userId = StpKit.ADMIN.getLoginIdAsLong();
//        Long userId = 11111111111111L;
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        OperateLog annotation = method.getAnnotation(OperateLog.class);
        //得到参数
        Object[] args = joinPoint.getArgs();
        //得到数据类型与操作类型
        String dateType = annotation.dateType();
        int operateType = annotation.operateType();
        //设置操作结果为成功，当发生异常时，设置其status为1；
        int status = 1;
        //根据operateType的设置操作数据为不同的数据；
        /**
         *  描述操作的类型:
         *  1. 新增
         *  2. 修改
         *  3. 单个删除
         *  4. 批量删除
         *  5. 修改状态
         *  6. excel导入
         *
         */

        String dataJsonStr = "";
        //针对新增和修改数据，我们可以将请求参数转化为json字符串，放入admin_operate_log中的data字段
        if (operateType == 1 || operateType == 4) {
            dataJsonStr = objectMapper.writeValueAsString(args);
        }


        Object result = null;
        try {
             result = joinPoint.proceed(args);
        } catch (Throwable e) {
            status = 0;
            throw new BusinessException(ResultCodeEnum.FAIL);
        }finally {
            //针对删除数据，因为无论是单个删除，还是批量删除，
            // 参数都只有id，所以我们把删除方法返回值转化为admin_operate_log的data字段
            //针对excel导入数据，我们也可以将返回值转化为json字符串
            if (operateType == 3 || operateType == 2 || operateType == 6 || operateType == 5) {
                dataJsonStr = objectMapper.writeValueAsString(result);
            }
            //这里进行插入数据！！！
            OperateLogDO operateLogDO = new OperateLogDO();
            operateLogDO.setEmployeeId(userId);
            operateLogDO.setDataType(dateType);
            operateLogDO.setOperateType(operateType);
            operateLogDO.setData(dataJsonStr);
            operateLogDO.setStatus(status);
            operateLogMapper.insert(operateLogDO);
        }
        //这个应该如何操作？
         // 针对修改数据，可以将参数封装为对象转化为json字符串，放入admin_operate_log中的data字段

        return result;
    }
}
